package com.etcn.modules.busi.order.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.etcn.common.Enum.DateFormat;
import com.etcn.common.exception.BusinessException;
import com.etcn.common.payment.alipay.constants.AlipayConstants;
import com.etcn.common.payment.wxpay.constants.WxPayConstants;
import com.etcn.common.payment.wxpay.util.WxPaySignature;
import com.etcn.common.payment.wxpay.util.WxPayUtil;
import com.etcn.common.service.impl.CrudServiceImpl;
import com.etcn.common.utils.DataUtil;
import com.etcn.common.utils.DateUtil;
import com.etcn.common.utils.IdWorker;
import com.etcn.common.utils.StringUtil;
import com.etcn.common.utils.UserUtil;
import com.etcn.common.utils.http.HttpSend;
import com.etcn.modules.busi.member.pojo.WmMember;
import com.etcn.modules.busi.member.service.IWmMemberService;
import com.etcn.modules.busi.order.dao.IWmOrderDao;
import com.etcn.modules.busi.order.pojo.WmOrder;
import com.etcn.modules.busi.order.service.IWmOrderService;
import com.etcn.modules.busi.product.pojo.WmVipProduct;
import com.etcn.modules.busi.product.service.IWmVipProductService;

/**
 * 订单serviceImpl
 *
 * @author guozc
 * @date 2018-03-19
 */
@Service("wmOrderService")
public class WmOrderServiceImpl extends CrudServiceImpl<IWmOrderDao, WmOrder> implements IWmOrderService {

	@Autowired
	private IWmVipProductService wmVipProductService;
	@Autowired
	private IWmMemberService wmMemberService;

	@Value("${server.url}")
	private String serverUrl;

	@Value("${server.ip}")
	private String serverIp;

	@Override
	public Map<String, Object> add(WmOrder entity) throws Exception {

		// 参数校验
		if (StringUtil.isEmpty(entity.getVipId())) {
			throw new BusinessException("vipId不能为空");
		}
		if (StringUtil.isEmpty(entity.getPayType())) {
			throw new BusinessException("payType不能为空");
		}
		// 保存订单信息
		IdWorker idWorker = new IdWorker(1, 1);
		String orderSn = String.valueOf(idWorker.nextId());
		entity.setOrderSn(orderSn);
		entity.setMemberId(UserUtil.getCurrentMemberId());
		String vipId = entity.getVipId();
		WmVipProduct vipProduct = wmVipProductService.getById(Long.parseLong(vipId));
		entity.setVipName(vipProduct.getVipName());
		entity.setOrderName(vipProduct.getVipName());
		entity.setOrderAmount(vipProduct.getVipPrice());
		entity.setOrderStatus("1");
		entity.setInvoiced("0");
		entity.setCreateTime(new Date());
		insert(entity);
		// 返回订单信息
		Map<String, Object> retMap = new HashMap<String, Object>();
		WmOrder order = getByOrderSn(orderSn);
		retMap.put("order", order);
		// 返回支付用签名后的参数
		Map<String, Object> paySign = null;
		if ("1".equals(entity.getPayType())) {
			paySign = alipayPrePay(order);
		} else if ("2".equals(entity.getPayType())) {
			paySign = wxPrePay(order);
		}
		retMap.put("paySign", paySign);
		return retMap;
	}

	@Override
	public List<WmOrder> getMemberOrders(WmOrder order) throws Exception {

		order.setMemberId(UserUtil.getCurrentMemberId());
		return dao.findList(order);
	}

	@Override
	public WmOrder getByOrderSn(String orderSn) throws Exception {

		return dao.getByOrderSn(orderSn);
	}

	@Override
	public Map<String, Object> alipayPrePay(WmOrder wmOrder) throws Exception {
		Map<String, Object> paySign = new HashMap<String, Object>();
		String orderName = "订单-"
				+ (wmOrder.getOrderName().length() > 20 ? wmOrder.getOrderName().substring(0, 20) : wmOrder.getOrderName());

		// 实例化客户端
		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayConstants.APPID,
				AlipayConstants.rsaPrivateKey, "json", AlipayConstants.INPUT_CHARSET, AlipayConstants.rsaPublicKey,
				AlipayConstants.SIGN_TYPE);
		// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		// SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setBody(orderName);
		model.setSubject(orderName);
		model.setOutTradeNo(wmOrder.getOrderSn());
		model.setTotalAmount(wmOrder.getOrderAmount());
		model.setProductCode("QUICK_MSECURITY_PAY");
		request.setBizModel(model);
		request.setNotifyUrl(serverUrl + "/orders/payNotify");
		try {
			// 这里和普通的接口调用不同，使用的是sdkExecute
			AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
			paySign.put("paystr", response.getBody());
			paySign.put("sign", "");
			paySign.put("timestamp", "");
			paySign.put("package", "");
			paySign.put("nonceStr", "");
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return paySign;
	}

	/**
	 * 微信统一下单
	 * 
	 * @param order
	 * @throws Exception
	 */
	public Map<String, Object> wxPrePay(WmOrder wmOrder) throws Exception {

		// 设置参数
		Map<String, Object> m = new HashMap<String, Object>();
		String orderName = "订单【" + wmOrder.getOrderSn() + "】";
		m.put("trade_type", "APP");
		m.put("appid", WxPayConstants.APP_ID);
		m.put("attach", orderName);
		m.put("body", "订单-"
				+ (wmOrder.getOrderName().length() > 20 ? wmOrder.getOrderName().substring(0, 20) : wmOrder.getOrderName()));// body限制长度20,过长会报错
		m.put("mch_id", WxPayConstants.MCH_ID);
		m.put("nonce_str", DataUtil.createUniqueCode());
		m.put("out_trade_no", wmOrder.getOrderSn() + "_" + System.currentTimeMillis() / 1000);
		m.put("spbill_create_ip", serverIp);
		m.put("notify_url", serverUrl + "/orders/wxPayNotify");
		Float payMoney = Float.parseFloat(wmOrder.getOrderAmount()) * 100;// 元转成分
		m.put("total_fee", payMoney.intValue());
		// 生成签名
		String sign = WxPaySignature.sign(m);
		m.put("sign", sign);
		// 发送请求
		HttpSend httpSend = new HttpSend();
		httpSend.sendNoJsonPost(WxPayConstants.UNIFIEDORDER_API, WxPayUtil.mapToXml(m));
		String retMsg = httpSend.returnMsg();
		// 返回xml类型字符串转换为map类型
		Map<String, Object> rt = WxPayUtil.xmlToMap(retMsg);
		Map<String, Object> appSignData = new HashMap<String, Object>();// 给app生成一个签名
		appSignData.put("appid", WxPayConstants.APP_ID);
		appSignData.put("partnerid", WxPayConstants.MCH_ID);
		appSignData.put("prepayid", rt.get("prepay_id"));
		appSignData.put("package", "Sign=WXPay");
		appSignData.put("noncestr", rt.get("nonce_str"));
		long timestamp = System.currentTimeMillis() / 1000;
		appSignData.put("timestamp", timestamp);
		String appSign = WxPaySignature.sign(appSignData);
		Map<String, Object> paySign = new HashMap<String, Object>();
		paySign.put("paystr", "");
		paySign.put("sign", appSign);
		paySign.put("prepayid", rt.get("prepay_id"));
		paySign.put("timestamp", timestamp);
		paySign.put("package", "Sign=WXPay");
		paySign.put("nonceStr", rt.get("nonce_str"));
		return paySign;
	}

	@Override
	public Map<String, Object> alipayPrePay(String orderSn) throws Exception {

		Map<String, Object> retMap = new HashMap<String, Object>();
		WmOrder order = getByOrderSn(orderSn);
		retMap.put("paySign", alipayPrePay(order));
		return retMap;
	}

	@Override
	public Map<String, Object> wxPrePay(String orderSn) throws Exception {

		Map<String, Object> retMap = new HashMap<String, Object>();
		WmOrder order = getByOrderSn(orderSn);
		retMap.put("paySign", wxPrePay(order));
		return retMap;
	}

	@Override
	public void payOrder(WmOrder wmOrder) throws Exception {

		WmOrder o = dao.getByOrderSn(wmOrder.getOrderSn());
		if (o == null) {
			return;
		}
		o.setOrderStatus("2");
		o.setPayTime(new Date());
		o.setPayType(wmOrder.getPayType());
		o.setPayAmount(wmOrder.getPayAmount());
		
		// 设置套餐
		WmVipProduct product = wmVipProductService.getById(Long.parseLong(o.getVipId()));
		Date vipEndTime = DateUtil.addDay(new Date(), product.getValidDay());
		o.setVipEndTime(vipEndTime);
		
		// 更新会员vip相关信息
		WmMember orderMember = wmMemberService.getByMemberId(o.getMemberId());
		if(orderMember != null){
			if("1".equals(orderMember.getVipFlag())){
				vipEndTime = DateUtil.addDay(DateUtil.formatStringToDate(orderMember.getVipEndTime(), DateFormat.Y_M_D_HMS), product.getValidDay());
			}
			WmMember member = new WmMember();
			member.setMemberId(o.getMemberId());
			member.setVipEndTime(DateUtil.formatDateToString(vipEndTime, DateFormat.Y_M_D_HMS));
			member.setVipProductId(o.getVipId());
			member.setVipFlag("1");
			wmMemberService.payUpdate(member);
		}
		
		dao.payUpdate(o);
	}

	@Override
	public void updateByOrderSn(WmOrder wmOrder) throws Exception {

		dao.updateByOrderSn(wmOrder);
	}

}